//
//  SafariExtensionViewController.m
//  DouyuAuth
//
//  Created by admin on 16/11/3.
//  Copyright © 2016年 douyu. All rights reserved.
//

#import "SafariExtensionViewController.h"
#import <JavaScriptCore/JavaScriptCore.h>
#import <AppKit/AppKit.h>
#import <Security/Security.h>

@interface SafariExtensionViewController ()
{
    JSContext *_jsContext;
    NSString *_authKey;
    NSTimer *_updateTimer;
    time_t _updateTime;
    long long _updateEpoch;
    
    __weak IBOutlet NSTextField *_textFieldAuthCode;
    __weak IBOutlet NSProgressIndicator *_progressIndicator;
}
@end

@implementation SafariExtensionViewController

+ (SafariExtensionViewController *)sharedController {
    static SafariExtensionViewController *sharedController = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedController = [[SafariExtensionViewController alloc] init];
    });
    return sharedController;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    _authKey = [self readAuthKey];
    
    [self loadAuthJS];
    
    NSClickGestureRecognizer *click = [[NSClickGestureRecognizer alloc] initWithTarget:self action:@selector(onClickGesture:)];
    [_textFieldAuthCode addGestureRecognizer:click];
}

- (void)onClickGesture:(NSClickGestureRecognizer *)clickGes
{
    // 复制到剪切板
    NSString *code = [_textFieldAuthCode.stringValue stringByReplacingOccurrencesOfString:@" " withString:@""];
    
    NSPasteboard *pb = [NSPasteboard generalPasteboard];
    [pb clearContents];
    [pb setString:code forType:NSStringPboardType];
    
    [self.presentingViewController dismissViewController:self];
    
    NSLog(@"已复制验证码:%@", code);
}

- (void)viewWillAppear
{
    [super viewWillAppear];
    
    _updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateAuthCode) userInfo:nil repeats:YES];
}

- (void)viewWillDisappear
{
    [super viewWillDisappear];
    [_updateTimer invalidate];
}

- (NSSize)preferredContentSize
{
    return NSMakeSize(332, 120);
}

- (NSSize)preferredMinimumSize
{
    return [self preferredContentSize];
}

- (void)updateAuthCode
{
    time_t nowTime = time(NULL);
    long long currentEpoch = nowTime/30;
    // 更新进度条
    double progress = nowTime%30;
    _progressIndicator.doubleValue = progress;
    
    // 更新验证码
    if (currentEpoch != _updateEpoch) {
        // 密钥过期，需要更新
        _updateTime = nowTime;
        _updateEpoch = currentEpoch;
        
        NSString *authCode = [self generateAuthCode:_authKey];
        NSMutableString *str = [[NSMutableString alloc] initWithString:authCode];
        [str insertString:@" " atIndex:3];
        [_textFieldAuthCode setStringValue:str];
    }
}

- (void)loadAuthJS
{
    _jsContext = [[JSContext alloc] init];
    
    NSString *authJSPath = [[NSBundle mainBundle] pathForResource:@"auth" ofType:@"js"];
    NSString *authJS = [NSString stringWithContentsOfFile:authJSPath encoding:NSUTF8StringEncoding error:nil];
    NSAssert(authJS.length > 0, @"加载JS失败");
    [_jsContext evaluateScript:authJS];
}

- (NSString *)generateAuthCode:(NSString *)authKey
{
    NSString *evaluateJS = [NSString stringWithFormat:@"getGoogleCode(\'%@\')", authKey];
    JSValue *value = [_jsContext evaluateScript:evaluateJS];
    NSLog(@"生成代码:%@", [value toString]);
    return [value toString];
}

#pragma mark - kaychain

- (NSString *)readAuthKey
{
    NSString *service = @"com.douyu.DouyuAuthHost";
    
    NSDictionary *query = @{
                            (id)kSecClass:(id)kSecClassGenericPassword,
                            (id)kSecAttrService:service,
                            (id)kSecAttrAccount:service,
                            (id)kSecReturnData:(id)kCFBooleanTrue
                            };
    CFDataRef data = NULL;
    OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&data);
    if (status != noErr) {
        NSLog(@"没有读取到密钥");
        return nil;
    }
    
    NSString *authKey = [[NSString alloc] initWithData:(__bridge NSData *)data encoding:NSUTF8StringEncoding];
    
    if (data) {
        CFRelease(data);
    }
    return authKey;
}

@end
